﻿using PacoToolKit.Format;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Protocol.SouthGridProtocol.Blocks
{
    public class Seq
    {
        /// <summary>
        /// TpV=0：表示无时间标签Tp；TpV=1：表示带有时间标签Tp
        /// </summary>
        public int tpv;

        /// <summary>
        /// FIR：置“1”，报文的第一帧,FIN：置“1”，报文的最后一帧
        /// </summary>
        public int fir;
        /// <summary>
        /// FIR：置“1”，报文的第一帧,FIN：置“1”，报文的最后一帧
        /// </summary>
        public int fin;

        /// <summary>
        /// 在所收到的报文中，CON位置“1”，表示需要对该帧报文进行确认；置“0”，表示不需要对该帧报文进行确认
        /// </summary>
        public int con;

        /// <summary>
        /// 启动帧序号PSEQ 响应帧序号RSEQ
        /// a） 启动帧序号PSEQ :启动站每发送1帧报文，该计数器加1，从0~15循环加1递增；重发帧则不加1
        /// b） 响应帧序号RSEQ: 响应帧序号RSEQ以启动报文中的PSEQ作为第一个响应帧序号，后续响应帧序号在RSEQ的基础上循环加1递增，数值范围为0~15。
        /// </summary>
        public int prseq;
        /// <summary>
        /// constract a seq
        /// </summary>
        /// <param name="msg"></param>
        public Seq(String hexSeqString)
        {
            try
            {
                //int seqInt = int.Parse(Formater.HEXtoDEC(hexSeqString));
                //tpv = (seqInt >= 128 ? 1 : 0);
                //fir = ((seqInt >= 64 && seqInt < 128) || (seqInt >= 192) ? 1 : 0);
                //fin = ((seqInt >= 32 && seqInt < 64) || (seqInt >= 224) ? 1 : 0);
                //con = ((seqInt >= 16 && seqInt < 32) || (seqInt >= 240) ? 1 : 0);
                //prseq = seqInt % 16;

                string seqBin = Formater.DECtoBIN(Formater.HEXtoDEC(hexSeqString), 8);
                tpv = int.Parse(seqBin.Substring(0, 1));
                fir = int.Parse(seqBin.Substring(1, 1));
                fin = int.Parse(seqBin.Substring(2, 1));
                con = int.Parse(seqBin.Substring(3, 1));
                prseq = int.Parse(Formater.BINtoDEC(seqBin.Substring(4, 4)));
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        /// <summary>
        /// constract a seq
        /// </summary>
        /// <param name="tpv">TpV=0：表示无时间标签Tp；TpV=1：表示带有时间标签Tp</param>
        /// <param name="fir">FIR：置“1”，报文的第一帧,FIN：置“1”，报文的最后一帧</param>
        /// <param name="fin">FIR：置“1”，报文的第一帧,FIN：置“1”，报文的最后一帧</param>
        /// <param name="con">CON位置“1”，表示需要对该帧报文进行确认；置“0”，表示不需要对该帧报文进行确认</param>
        /// <param name="prseq">启动帧序号PSEQ 响应帧序号RSEQ</param>
        public Seq(int tpv, int fir, int fin, int con, int prseq)
        {
            this.tpv = tpv; this.fir = fir; this.fin = fin; this.con = con; this.prseq = prseq;
        }
        /// <summary>
        /// 根绝seq内容组合成新的seq hex string值
        /// </summary>
        /// <returns></returns>
        public String encodeSeqString()
        {
            /*
            String binString = String.valueOf(tpv) + String.valueOf(fir) + String.valueOf(fin) + String.valueOf(con) 
                + Convertor.setLengthBinsString(Convertor.decStringToBin(String.valueOf(prseq)), 4);
            return Convertor.binStringToHex(binString).toUpperCase();
             * */
            string binString = tpv.ToString() + fir.ToString() + fin.ToString() + con.ToString() + Formater.DECtoBIN(prseq.ToString(), 4);
            return Formater.DECtoHEX(Formater.BINtoDEC(binString), 2).ToUpper();
        }
        public string encodeSeqString(int tpv, int fir, int fin, int con, int prseq)
        {
            string binString = tpv.ToString() + fir.ToString() + fin.ToString() + con.ToString() + Formater.DECtoBIN(prseq.ToString(), 4);
            return Formater.DECtoHEX(Formater.BINtoDEC(binString), 2).ToUpper();
        }
    }
}
